package com.chain.galaxychain123.kotlionapp

import android.os.Bundle
import android.support.v7.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

 /*
 *   var 变量 可以修改
 * */
        var b:Byte=-127;
             b=127;

           //自动匹配为int类型
        var a:Int=18;
           a=19;
          a=20;
       var     b2:Int=20;
              b2=21;
        //自动匹配为string类型
        var s:String="hello word";
            s="hello kotlion"
       // 自动匹配为long类型
        var l:Long=2000000000000000000;
            l=2000000000000000001;

        var  v: Float=1.848745738548590827489207289754378970377920875894781f;


   /*
   val 常量 只读 不可修改

   */

   val name:String="方明飞"
       // name="haha"

  //=============================================================================


  var  nameStr:String="黑马程序员";
        for (c in nameStr) {
           println(c)
        }



  /*Kotlin 还新增了一种做法，字符串可以由三重引号（”””）分割，可以直接包含任
意的特殊字符，参考代码：
*/

        val str2 = """
   Kotlin 的字符串输出函数是 println 和 print，
   相比 Java 的 System.out.println 以及
System.out.print 代码量还是要
"""

  println(str2)
//==========================
  //kotlion 的字符串截取
//1. Kotlin的split方法还允许传入多个拆分符
   var v1="hello.kotlion-itheima*world/java"
   println(v1.split(".","-","*","/"))

//2. Kotlin的截取方法：substring()、substringBeforeLast()、substringAfterLast()

//3. Kotlin的去空格
 /*
        trim：去除字符串前后空格
        trimStart：去除字符串前面空格
        trimEnd：去除字符串后面空格
        trimMargin  可以去掉前导空格

 */







  //字符串模板
//1.在字符串中进行变量输出，语法格式 "*****${变量}*******"
println(diaryGenerate1("方明飞",31,"西二旗",1500.789f,true))

//2.在字符串中调用其他方法，语法格式${方法()}
  //"******${方法1()}***,******${方法2()}******"
var vv="下面我坐下自我介绍${diaryGenerate1("方明飞",31,"西二旗",1500.789f,true)},然后就是${diaryGenerate2()}"
  println(vv)



        //===================================================
   val  str = "方明飞"
        getString(str)

   //============================
       //可空类型变量?
        var age:String?="21"
        //使用安全符?
        var result:Int? = age?.toInt()
        println("result:${result}") //21





    //==============================

      //可空类型变量
        var age2:String?="22"
      //使用非空断言!!
      //  var result2 =age2!!.toInt()

     ///   println(result2) //22


  //======================================
   val intRange =1..10


     // Range-->arr
     val array=    arrayOf(intRange)
        println(array)

      //range-->List
      val  list=intRange.toList()
       println(list)

        val set=intRange.toSet()
        println(set)


        //====================
        var nums=1..100

        var result2=0
        for (num in nums) {
            result2=result2+num
           println("${num}")
        }

        println("结果${result2}")


    //========================
        //创建可读可写的集合
        val list3= arrayListOf<Int>()
        list3.add(1)
        list3.add(2)
        list3.add(3)

        for (i in list3) {
            println(i)
        }

        //创建可读可写的集合
        val list2  = mutableListOf<String>()
        //添加元素
         list2.add("冠军")
         list2.add("明飞")
         list2.add(2,"哈哈") //在指定位置添加集合元素
         list2.add("嘻嘻")
         print("集合"+list2)
       //高级for 循环
        for (s in list2) {
            println(s)
        }

          //根据withIndex 循环
        for(withIndex in list2.withIndex()){
            println("集合角标index:${withIndex.index},集合元素值value:${withIndex.value}")
        }

     //get方法 获取指定位置的元素值
      var element:String?=    list2.get(1)
      println("${element}")  //明飞
        //通过下标Index  获取指定位置的元素
       var element1:String?=list2[1]
        println("${element1}")  //明飞
       //通过getOrNull 获取指定位置index的集合元素值  获取成功
        var element2:String?=list2.getOrNull(1)
        println("${element2}")  //明飞
        //通过getOrNull 获取指定位置index的集合元素值 获取失败 返回null
        var element3:String?=list2.getOrNull(99)
        println("${element3}")  //null


        var  index=list2.indexOf("冠军")
        println(index)  //index =0

//========================================
    val map1 = mapOf<String,Int>(Pair("佳佳",20),Pair("悄悄",21),Pair("依依",22))
        println(map1)
        //map集合不可写 需要转为MutableMap集合才可写
        val map2=mapOf<String,Int>().toMutableMap()
        map2.put("佳佳1",20);
        map2.put("佳佳2",21);
        map2.put("佳佳3",22);
        println(map2)


     val hashMap1= hashMapOf<String,Int>(Pair("佳佳",20),Pair("悄悄",21),Pair("依依",22))
        println("hashMap1->${hashMap1}")
        val hashMap2= hashMapOf<String,Int>()
        hashMap2.put("悄悄1",20)
        hashMap2.put("悄悄2",21)
        hashMap2.put("悄悄3",22)
        println("hashMap2->${hashMap2}")


     val   mutableMap1= mutableMapOf<String,Int>(Pair("佳佳",20),Pair("悄悄",21),Pair("依依",22))
        println("mutableMap1->${hashMap1}")

        val   mutableMap2= mutableMapOf<String,Int>()
        mutableMap2.put("依依1",20)
        mutableMap2.put("依依2",21)
        mutableMap2.put("依依3",22)
        println("mutableMap2->${mutableMap2}")

    //============================
        //map集合的便利
        for (mutableEntry in mutableMap1) {
            println("key->${mutableEntry.key}")
            println("value->${mutableEntry.value}")
        }




   //===========================

        var person  =Person()
        person.toString()
         println("${person.toString()}")
        person.name="方明飞"
        println("姓名:${person.name}")
        person.age=32
        println("年龄:${person.age}")



    //=========================
        //通过 主构造函数  创建对象
        var student = Student("张三",18)
         student.printPersonInfo()



     //=============================
         //Ktlion 的外部类嵌套内部类
        //外部类对象
        val outer= Outer()
        println("${outer.outerOfVal}")
         outer.outerOfVal="外部类的属性的修改"
        println("${outer.outerOfVal}")

        //内部类对象
         var inner = outer.Inner();
         println("${inner.innerOfVal}")
          inner.innerOfVal="内部类的属性的修改"
        println("${inner.innerOfVal}")
        //访问内部类的方法
        inner.innerFun()

//==================================
        //枚举
        //遍历枚举
        for (value in Week.values()) {
            println("${value.ordinal}+${value.name}")
        }

        //获取枚举的name ordinal属性
        println("${Week.FRI.ordinal}+${Week.FRI.name}")

//==========================

    println("${Day.MONRING.ordinal}"+"${Day.MONRING.name}"+"${Day.MONRING.what}"+"${Day.MONRING.doSomething}")// 0 MONRING 早上 吃早饭
   println("${Day.MOON.ordinal}"+"${Day.MOON.name}"+"${Day.MOON.what}"+"${Day.MOON.doSomething}")// 1 MOON 中午 吃午饭


//==========================
   // val man:People=Man("男人")
   val  man = Man("男人")
    println("${man.name},${man.eat()},${man.niaoniao()},${man.hairStyle},${man.BodyWeight()},${man.Skin},${man.drive()},${man.write()}")//男人,吃饭,男人站着尿尿,男人短头发,男人重,男人皮肤黑,会开车，写作。

   val women=Woman("女人")
   println("${women.name},${women.eat()},${women.niaoniao()},${women.hairStyle},${women.BodyWeight()},${women.Skin},${women.drive()},${women.write()}")//女人,吃饭,女人蹲着尿尿,女人长头发,女人轻,女人皮肤白,会开车，写作

 //高级经理  聘司机开车CarDriver    聘秘书写作PPTWriter
  val carDriver=CarDriver()
  val pptWriter = PPTWriter()
 val seniorManager = SeniorManager(carDriver, pptWriter)
 println("高级经理:${seniorManager.drive()}+${seniorManager.write()}") //聘司机开车 秘书写作


//==================

        val button=Button()
        button.OnceClick()
        button.twiceClick()


   //===========
        var textView= TextView()
          textView.setOnClickListener(object:TextView.OnClickListener{
              override fun onClick(textSize: Int) {
               println("文本框的字体大小:${textSize}") //文本框的字体大小:15
              }
          })

//==================
       val dog = object : Animal(){
           override fun eat(food: String) {
              println("狗吃啥:${food}")
           }
       }

        dog.eat("")

   //访问伴生对象的方法和属性
      A.b()
        A.b()
      println("访问伴生对象B的属性=${A.b}")
        println("访问伴生对象B的属性=${A.b}")

  //======================
   var  color:Color?=Color.RED
        when(color){
           //判断是否是Color枚举类型
            is Color -> println("是Color枚举类型")
            //判断是否是 RED
              Color.RED    -> println("是红色")
          //判断是否是 GREEN,BLUE
            Color.GREEN,Color.BLUE    -> println("是绿色或蓝色")
        }

    //====================

    //常见的for 循环
      val range = 1..10

        for (index in range.withIndex()) {
             println("${index.index}+${index.value}")
        }

      var x=10
        while(x>=0){
            if(x%2==0)println(x)
            x--
        }

      for(i  in 1..10){
          println(i)
          if(i==5){break}
      }


        // ! 逻辑非 not()
         println(!true)
        println(true.not())

   // && 短路逻辑与 and()
      println(true&&true)
        println(true.and(true)) //true
        println(true.and(false)) //false

    //            || 短路逻辑或or()
     println(true || false) //true
        println(true.or(false)) //true
        println(false.or(true)) //false
        println(false.or(false)) //false

  println("abcd"[1]) //b


        val list_1 = listOf(0,1, 2, 3, 4, 5, 6,7,8,9)
        val list_2 = arrayListOf(0,1,2,3)
        list_2.add(4)
        list_2.add(5)
        list_2.add(6)




        val tChar: Char = '\t' // 制表符
        println("tChar"+tChar)

        val  pointChar: Char = '\''
        println("pointChar"+pointChar) // '

        val nChar: Char = '\\'
        println("nChar"+nChar)  //   \


        val arg1: Int = 0
        val arg2: Int = 1

        println("${arg1} + ${arg2} = ${arg1 + arg2}") //0 + 1 = 1

        println("\$salary") //$salary  (\ 转义  \$ 表示$字符)
        val salary: Int = 1000
        println("${salary}") // 1000
        println("$${salary}") //$1000
        println("\$${salary}") //$1000

        val string0: String = "Hello"
        println(string0.length) //5
        val string1: String=""
        println(string1.length) //0
        val string2: String?= null
         println(string2?.length) //null
        val string3: String? = "Hello"
        println(string3?.length) //5



        val parent: Parent = Parent()
       // val child: Child? = parent as Child //as 转换类型失败 抛出异常
        val child: Child? = parent as? Child //as?  转换类型失败 输出null
         println(child?.name) //null



        val  intrange:IntRange = 1..10

        for (i in intrange) {
            println("${i},")
        }

        val arrayOfChar: CharArray = charArrayOf('H', 'e','l','l','o','W','o','r','l','d')
       //joinToString 把字符串数组 里的所有的字符链接起来输出  helloword
        println(arrayOfChar.joinToString("")) //HelloWorld
        //slice 获取数组某区间的元素
        println(arrayOfChar.slice(1..3))  //[e, l, l]



        println(int2Long(3))  //3

        //输出lamuda表达式值 4
        //sum(1,3) = sum.invoke(1,3)
        println(sum(1,3))


        //============
        val aa= AA()
        println(aa.e) //初始化 类 X
        println(aa.b) //b=0

        aa.x = X()
        println("先初始化x值:"+aa.x) //先要对x进行初始化赋值 aa.x = X()=X@7fe5cec

        aa.str="哈哈"
        println(aa.str) //先要对aa.str进行初始化赋值  哈哈

        println(aa.s?.length) // 无长度 null
        aa.s="kotlin" //对aa.s 进行初始化赋值
        println(aa.s?.length) //length=6
        println(aa.ss) //aa.ss="方明飞"
//===============================
        var arrayy = intArrayOf(1,2,3,4,5)
        //调用一个函数  带有  具名参数(初始化值ouble=3.0)  变长参数intsArr=*arrayy, 和 具名参数 string="helloword"
         //*arrayy  *表示把数组arrayy展开
        hello(double=1.0,intsArr=*arrayy,string="helloword")

         //或者也可以这样写
        hello(3.0,*arrayy,string="你好")


        hello(intsArr=*arrayy,string="我不好")

        hello(intsArr=*arrayy)
  //===========================================================
        val  input =" 3 + 4 "
        val splits =input.trim().split(" ")
        val arg11=splits[0].toDouble() //3
        val op=splits[1] //+
        val arg22=splits[2].toDouble() //4
        println("${arg11}${op}${arg11}=${Operator(op).invoke(arg11, arg22)}") // 3.0+3.0=7.0

//================

  //在kotlin类里调用默认函数
    val overloads =Overloads()
    val int1:Int=  overloads.a()
        println("在kotlin里调用默认函数输出默认结果int1=${int1}")  //int1=0
      val int2:Int= overloads.a(int=100)
        println("在kotlin里调用默认函数改变默认函数参数初始化值int2=${int2}")  //int2=100

//========================
        //自定义 get  set
     var   bigson = BigSon()
        println("大头儿子的默认属性输出值:${bigson.name}年龄${bigson.age}")  // 大头儿子的默认属性:大头儿子年龄1

    //修改属性age (=java的set())
        bigson.age=18
        println("大头儿子的修改属性输出值:${bigson.name}年龄${bigson.age}") //大头儿子的修改属性输出值:大头儿子年龄18

    //小头爸爸给大头儿子的压岁钱ashuMoney=100
        //触发SmallFather的setValue()方法
        bigson.yashuMoney=100
        println("大头儿子的压岁钱:${bigson.yashuMoney}") // 大头儿子的压岁钱:100
   // 大头儿子 买了个玩具-50
        bigson.yashuMoney=bigson.yashuMoney-50
        println("大头儿子的压岁钱还剩:${bigson.yashuMoney}") //大头儿子的压岁钱还剩:50

    }

   /*class Overloads{

      //  在java类里如何调用kotlin的默认函数 呢？
      //在kotlin的默认函数上必须加@JvmOverloads注解,就能被java调用使用了
      @JvmOverloads
      fun a(int:Int=0):Int{return int}  //默认函数  参数int默认初始化值0
 }*/


class Operator(op:String){
    operator fun invoke(left: Double, right: Double): Double {
        return opFun(left,right)

    }

   // private fun opFun(left: Double, right: Double): Double {}
   val opFun: (left: Double, right: Double) -> Double

    init{
        opFun = when(op){
           "+" -> { l, r -> l + r }
           "-" -> { l, r -> l - r }
           "*" -> { l,  r -> l * r }
           "/" -> { l, r -> l / r }
           "%" -> { l, r -> l % r }
           else -> {
               //否者 输出 异常信息
               throw UnsupportedOperationException(op)
           }
       }
    }

}







    //变长参数 只能是参数的最后一个参数
    fun hello(double:Double=0.0,vararg intsArr:Int, string:String=""){
        println(double) //3.0
        for (i in intsArr) {
            println("变长参数的元素:"+i)//12345
        }

        println("具名参数:"+string) //具名参数:helloword
    }



    fun main(vararg args:String){
        for (arg in args) {
            println(arg)
        }
    }





//sum函数常规写法
//fun sum(arg1:Int,arg2:Int):Int{ return arg1+arg2 }

    //sum函数的简单写法
 //fun sum(arg1:Int,arg2:Int)=arg1+arg2


   // sum函数 用lambda 表达式 来表示
    // val sum = {x: Int,y: Int -> x + y}
 //  参数 ->  返回值      (Int,Int)->Int

val sum = {arg1:Int,arg2:Int->arg1+arg2}








//匿名函数  可以变量=无名函数
val int2Long=fun(x:Int):Long{return x.toLong() }




   fun switch(x:Any){
       when(x){
         is String ->println("是String类型")
           !is String -> println("不是String类型")
           is Long -> println("这是一个Long类型数据")
           -1, 0 -> println("x == -1 or x == 0")
           1 -> println("x == 1")
           //in 1..10 -> println("x is in the range")
           else -> print("else类似于Java中的default")
       }
   }




    enum class Color{RED,GREEN,BLUE}




    fun max(a:Int,b:Int):Int{
        var max:Int
        if(a>b){
            max=a
        }else{
            max=b
        }

        return max
    }

    fun score(  score:Int){
        if(score>=85&&score<=100){
            println("优")
        }else if(score>=70&&score<85){
            println("良")
        }else if(score>=60&&score<69){
            println("中")
        }else{
            println("差")
        }

    }


    fun score2(  score:Int){
      when(score){
          in 85..100 ->println("优")
          in 70 until 85 ->println("良")
          in 60 until 70 ->println("中")
          in 0..60 -> println("差")
          else -> println("无结果")
      }

    }





 class A{
     val a:String="a"
     fun a():Unit{
         println("外部类A的方法")
     }

     companion object B:BInterface,C(){
     var b:String="b"
         fun b():Unit{
             println("我是伴生对象B的方法")
         }
     }


 }



    interface  BInterface{}
    open class C(){}




    fun getString(obj:Any){
     if(obj is String){
         println("obj是"+obj+"obj的长度"+obj.length)
     }else{
         return
     }
 }





    fun diaryGenerate1(placeName:String,age:Int,work:String,gongzi:Float,sex:Boolean):String{
        var temple=
            """
            我是${placeName},
            今年${age}岁,
            工作是${work},
             工资每月${gongzi}，
             性别${sex}
            """
       return temple;
    }



    fun diaryGenerate2():String{
        return "具体做安卓开发,项目斗币"
    }






}
